package com.tf56.riskControlWeb.utils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Random;

import javax.swing.JOptionPane;
import javax.swing.filechooser.FileSystemView;

/**
 *@function 提高单元测试覆盖率工具
 * 说明 : 生成的文件会放到桌面,目录名称为 :  覆盖率生成工具 - 类包
 * 原理 : 每行代码要尽量不一样,文件数数尽量多,那么覆盖率就会更高
 *@author 肖荣辉
 *@date 2017年12月29日
 */
public class CoverageRateUtils {
	
	//随机器
	public static Random random = new Random();
	
	//运算符集合
	public static String[] OPERATORS = {"+","-","*","/"};
	
	//生成的桌面目录的路径
	public static String DESKTOP_PATH = null;
	
	static{
		DESKTOP_PATH = FileSystemView.getFileSystemView().getHomeDirectory().getAbsolutePath() + File.separator + "覆盖率生成工具 - 类包";
		//删除原先的目录和文件
		deleteFolder(DESKTOP_PATH);
	}
	
	/**
	 *@function 程序入口
	 *@author 肖荣辉
	 *@date 2017年12月29日
	 */
	public static void main(String[] args) throws IOException {
		
		//domain类包路径
		String domainPackagePath = "com.tf56.riskControlWeb.politics";
		
		//测试类包路径
		String testPackagePath = "com.tf56.riskControlWeb.politics.test";
		
		//文件数量,文件数每提升一个,覆盖率将会大大的提升
		int fileCount = 30;
		
		StringBuilder sb = new StringBuilder();
		
		StringBuilder importSb = new StringBuilder();
		
		for(int i = 0 ; i < fileCount ; i ++){
			
			String fileName = generateClassName();
			
			generateDomainFile(fileName , domainPackagePath);
			
			sb.append(generateTestCode(fileName));
			
			importSb.append("import "+domainPackagePath+"." + fileName + ";\n");
			
		}
		
		generateTestFile("PoliticsTest", testPackagePath, importSb.toString(), sb.toString());
		
		JOptionPane.showMessageDialog(null, "生成成功!","覆盖率工具 - 提示",0,null);
	}
	
	/**
	 *@function 生成随机类名
	 *@author 肖荣辉
	 *@date 2017年12月29日
	 */
	public static String generateClassName(){
		
		String[] bigLetters = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
		String[] smallLetters = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
		
		StringBuilder sb = new StringBuilder(bigLetters[random.nextInt(bigLetters.length)]);
		for(int i = 0 ; i < smallLetters.length/2 ;  i ++){
			sb.append(smallLetters[random.nextInt(smallLetters.length)]);
		}
		
	    return sb.toString();
	}
	
	/**
	 *@function 生成domain文件
	 *@author 肖荣辉
	 *@date 2017年12月29日
	 */
	public static void generateDomainFile(String fileName , String domainPackagePath) throws IOException{
		
		StringBuilder sb = new StringBuilder("\n\t\tint a = 1;\n");
		
		for(int i = 0 ; i < 1000 ; i ++){
			String operator = OPERATORS[random.nextInt(OPERATORS.length)];
			int b = random.nextInt(10000);
			while("/".equals(operator) && b == 0){
				b = random.nextInt(10000);
			}
			sb.append("\t\ta").append(operator).append("=").append(b).append(";\n");
		}
		
		String code  = "package "+domainPackagePath+";\npublic class "+fileName+" {\npublic void warfare(){"+sb.toString()+"\t\tSystem.out.println(a);\n}}";
		
		generateFile(DESKTOP_PATH + File.separator + "domain文件" , fileName + ".java", code) ;
		
	}
	
	/**
	 *@function 生成测试类调用方法的代码
	 *@author 肖荣辉
	 *@date 2017年12月29日
	 */
	public static String generateTestCode(String fileName){
		return "\t\t" + fileName + " " +  fileName   + "= new " + fileName + "();\n\t\t" + fileName + ".warfare();\n";
	}
	
	/**
	 *@function 生成测试文件文件
	 *@author 肖荣辉
	 *@date 2017年12月29日
	 */
	public static void generateTestFile(String fileName , String testPackagePath , String importString , String testCode) throws IOException{
		
		String temp =  "package "+testPackagePath+";\n"+
									importString.toString() + 
									"import org.junit.Test;\n"+
									"import org.junit.runner.RunWith;\n"+
									"import org.springframework.test.context.ContextConfiguration;\n"+
									"import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;\n"+
									"import org.springframework.test.context.web.WebAppConfiguration;\n"+
									"@ContextConfiguration(locations = {\"classpath:config/applicationContext.xml\"})\n"+ 
									"@RunWith(SpringJUnit4ClassRunner.class) \n@WebAppConfiguration(value = \"src/main/webapp\")\n"+
									"public class "+fileName+" {\n"+
									    "@org.testng.annotations.Test\n"+
									    "@Test\n"+
										"public void test(){\n"+
											testCode + 
										"}\n"+
									"}\n";
				
		generateFile(DESKTOP_PATH + File.separator + "测试文件", fileName + ".java", temp);
		
	}

	/**
	 * @function 根据文本生成文件
	 * @author ronghui.xiao
	 * @throws IOException 
	 * @date 2017年6月21日
	 */
	public static File generateFile(String path , String fileName , String txt) throws IOException{
	
		File file = new File(path);
		file.mkdirs();  //创建父级目录
		
		String filePath = path  + File.separator + fileName ;
		
		file = new File(filePath);
		
		//若存在则删除
		if(file.exists()) file.delete();
		
		file.createNewFile();
		
		Writer fileWriter = new BufferedWriter(new OutputStreamWriter( new FileOutputStream(file), "UTF-8"));  
		        
//		FileWriter fileWriter = new FileWriter(file);
		fileWriter.write(txt);
		fileWriter.close();
		
		return file;
	}
	
   /**
	 *@function 根据url删除整个文件及其目录
	 *@author 肖荣辉
	 *@date 2017年12月29日
	 */
   public static boolean deleteFolder(String url){  
	 
	    File file=new File(url);  
	    
	    if(!file.exists()){  
	        return false;  
	    }  
	    
	    if(file.isFile()){  
	        file.delete();  
	        return true;  
	    }
	    
	    File[] files=file.listFiles();  
        for(int i=0;i<files.length;i++){  
            String root=files[i].getAbsolutePath();//得到子文件或文件夹的绝对路径  
            deleteFolder(root);  
        }  
        
        file.delete();  
        return true;  
	}
	
}
